package ext.tianma.project2.APQP.queue;

import java.io.IOException;
import java.sql.Timestamp;
import java.text.ParseException;
import java.util.*;

import org.apache.commons.lang.StringUtils;
import org.dom4j.DocumentException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import wt.fc.PersistenceHelper;
import wt.fc.QueryResult;
import wt.fc.collections.WTHashSet;
import wt.fc.collections.WTSet;
import wt.inf.team.ContainerTeamManagedState;
import wt.org.WTUser;
import wt.projmgmt.admin.Project2;
import wt.query.ArrayExpression;
import wt.query.ClassAttribute;
import wt.query.QuerySpec;
import wt.query.SearchCondition;
import wt.util.WTException;
import wt.util.WTPropertyVetoException;

import com.ptc.projectmanagement.plan.PlanActivity;
import com.ptc.projectmanagement.plan.PlannableState;

import ext.tianma.project2.APQP.constants.APQPProjectConstant;
import ext.tianma.project2.APQP.service.APQPConfig;
import ext.tianma.project2.util.ProjectUtil;
import ext.tianma.util.TMUtil;

/**
 * @author Elead
 */
public class RunQueue {
	private static final Logger logger = LoggerFactory.getLogger(SendEMail.class);
   
    /**
     * 查询符合时间任务
     *
     * @param projectStates 项目状态
     * @param planStates    任务状态
     * @param hierarchy     层级
     * @return
     * @throws IOException 
     * @throws DocumentException 
     */
    public static QuerySpec getPlanActivity(String[] projectStates, String[] planStates, String[] hierarchy)
            throws WTException, ParseException, DocumentException, IOException {
        //state 所有的项目状态
        ArrayExpression state = new ArrayExpression(projectStates);
        //state1 所有的任务状态
        ArrayExpression state1 = new ArrayExpression(planStates);
        //string 层级名称
        ArrayExpression string = new ArrayExpression(hierarchy);

        QuerySpec qs = new QuerySpec();
        /* 启用高级查询 */
        qs.setAdvancedQueryEnabled(true);
        //多表查询用到的表，参数为true，表示结果集可以返回
        int pa = qs.addClassList(PlanActivity.class, true);
        int p2 = qs.addClassList(Project2.class, false);


        //关联查询，返回 p2.ida2a2 = pa.ida3Containerreference
        SearchCondition sc = new SearchCondition(PlanActivity.class, "containerReference.key.id",
                Project2.class, "thePersistInfo.theObjectIdentifier.id");
        qs.appendWhere(sc, new int[]{pa, p2});

        //项目状态
        ClassAttribute ca = new ClassAttribute(Project2.class, "containerTeamManagedInfo.state");
        SearchCondition sc3 = new SearchCondition(ca, SearchCondition.IN, state);
        qs.appendAnd();
        qs.appendWhere(sc3, new int[]{p2});

        //活动状态
        ClassAttribute ca1 = new ClassAttribute(PlanActivity.class, "plannableState");
        SearchCondition sc2 = new SearchCondition(ca1, SearchCondition.IN, state1);
        qs.appendAnd();
        qs.appendWhere(sc2, new int[]{pa});


        /**
         * 得到指定天数后的日期
         * 再获取该日期之前的满足条件的活动
         * 
         * dateKey = Integer.valueOf(key) + 1
         * 因为该日期拿到的是指定日期的00:00:00之前的数据，若要满足当前的，则必须要+1
         * */
        int dateKey = 7;
        String key = APQPConfig.getKey("PlanDay");
        if(StringUtils.isNumeric(key)) {
        	dateKey = Integer.valueOf(key) + 1;
        }
        Date tempDate = TMUtil.getCurrentDate("yyyy-MM-dd");
        Date date = TMUtil.addDate(tempDate, +dateKey, 0, 0);
//        //设置显示格式
//        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
//        //string转换成date格式
//        Date date = sf.parse(str);
        SearchCondition sc4 = new SearchCondition(PlanActivity.class, PlanActivity.START_DATE,
                SearchCondition.LESS_THAN_OR_EQUAL, new java.sql.Timestamp(date.getTime()));
        qs.appendAnd();
        qs.appendWhere(sc4, new int[]{pa});

        //lineNumber != 0
        SearchCondition sc5 = new SearchCondition(PlanActivity.class, PlanActivity.LINE_NUMBER,
                SearchCondition.NOT_EQUAL, 0);
        qs.appendAnd();
        qs.appendWhere(sc5, new int[]{pa});

        logger.info("qs>>>>>>>>>" + qs.toString());
        //层级
        if (hierarchy != null) {
            String hierarchyQueryName = ProjectUtil.getQueryName("hierarchy",
                    APQPProjectConstant.APQP_PLANACTIVITY);
            ClassAttribute ca2 = new ClassAttribute(PlanActivity.class, hierarchyQueryName);
            SearchCondition sc6 = new SearchCondition(ca2, SearchCondition.IN, string);
            qs.appendAnd();
            qs.appendWhere(sc6, new int[]{pa});
        }
        return qs;
    }


    /**
     * 查询所有超时的任务,使用开始时间判断
     * @param projectStates 项目状态
     * @param planStates    任务状态
     * @param hierarchy     层级
     * @return
     * @throws IOException
     * @throws DocumentException
     */
    public static QuerySpec getPlanActivityDelay(String[] projectStates, String[] planStates, String[] hierarchy)
            throws WTException, ParseException, DocumentException, IOException {
        //state 所有的项目状态
        ArrayExpression state = new ArrayExpression(projectStates);
        //state1 所有的任务状态
        ArrayExpression state1 = new ArrayExpression(planStates);
        //string 层级名称
        ArrayExpression string = new ArrayExpression(hierarchy);

        QuerySpec qs = new QuerySpec();
        /* 启用高级查询 */
        qs.setAdvancedQueryEnabled(true);
        //多表查询用到的表，参数为true，表示结果集可以返回
        int pa = qs.addClassList(PlanActivity.class, true);
        int p2 = qs.addClassList(Project2.class, false);

        //关联查询，返回 p2.ida2a2 = pa.ida3Containerreference
        SearchCondition sc = new SearchCondition(PlanActivity.class, "containerReference.key.id",
                Project2.class, "thePersistInfo.theObjectIdentifier.id");
        qs.appendWhere(sc, new int[]{pa, p2});

        //项目状态
        ClassAttribute ca = new ClassAttribute(Project2.class, "containerTeamManagedInfo.state");
        SearchCondition sc3 = new SearchCondition(ca, SearchCondition.IN, state);
        qs.appendAnd();
        qs.appendWhere(sc3, new int[]{p2});

        //活动状态
        ClassAttribute ca1 = new ClassAttribute(PlanActivity.class, "plannableState");
        SearchCondition sc2 = new SearchCondition(ca1, SearchCondition.IN, state1);
        qs.appendAnd();
        qs.appendWhere(sc2, new int[]{pa});

        /**
         * 得到指定天数后的日期,并获取所有开始时间在之前的任务,当天不算过期
         * */

        Date tempDate = TMUtil.getCurrentDate("yyyy-MM-dd");
        Date date = TMUtil.addDate(tempDate, +1, 0, 0);

        SearchCondition sc4 = new SearchCondition(PlanActivity.class, PlanActivity.START_DATE,
                SearchCondition.LESS_THAN_OR_EQUAL, new java.sql.Timestamp(date.getTime()));
        qs.appendAnd();
        qs.appendWhere(sc4, new int[]{pa});

        //lineNumber != 0
        SearchCondition sc5 = new SearchCondition(PlanActivity.class, PlanActivity.LINE_NUMBER,
                SearchCondition.NOT_EQUAL, 0);
        qs.appendAnd();
        qs.appendWhere(sc5, new int[]{pa});

        logger.info("qs>>>>>>>>>" + qs.toString());
        //层级
        if (hierarchy != null) {
            String hierarchyQueryName = ProjectUtil.getQueryName("hierarchy",
                    APQPProjectConstant.APQP_PLANACTIVITY);
            ClassAttribute ca2 = new ClassAttribute(PlanActivity.class, hierarchyQueryName);
            SearchCondition sc6 = new SearchCondition(ca2, SearchCondition.IN, string);
            qs.appendAnd();
            qs.appendWhere(sc6, new int[]{pa});
        }
        return qs;
    }

    /**
     * 修改任务状态
     * @param projectStates
     * @param planStates
     * @param hierarchy
     * @return
     * @throws WTPropertyVetoException
     * @throws IOException 
     * @throws DocumentException 
     */
    public static Boolean runScheduleQueue()
            throws WTPropertyVetoException, IOException, DocumentException {
        WTSet set = new WTHashSet();
        
        String[] projectStates = {ContainerTeamManagedState.RUNNING.toString()};
        String[] planStates = {PlannableState.SCHEDULED.toString()};
        String[] hierarchy = {"L2"};
        try {
        	QuerySpec qs = getPlanActivity(projectStates, planStates, hierarchy);
            QueryResult queryResult = PersistenceHelper.manager.find(qs);
            logger.info("runScheduleQueue qs>>>>>>" + qs.toString());
            Date date = new Date();
            while (queryResult.hasMoreElements()) {
                Object[] obj = (Object[]) queryResult.nextElement();
                PlanActivity activity = (PlanActivity) obj[0];
                activity.setPlannableState(PlannableState.INPROCESS);
                activity.setActualStartDate(new Timestamp(date.getTime()));
                set.add(activity);
            }
            if(set.size() > 0) {
            	Map<WTUser, List<PlanActivity>> maps = SendEMail.getUserAllTask(qs);
            	PersistenceHelper.manager.save(set);
                SendEMail.email(maps);
            }

            set.clear();
            String[] inprocess = {PlannableState.INPROCESS.toString()};
            QuerySpec qs2 = getPlanActivity(projectStates, inprocess, hierarchy);
            QueryResult queryResult2 = PersistenceHelper.manager.find(qs2);
            Map<WTUser, List<PlanActivity>> acts = new HashMap<WTUser, List<PlanActivity>>();
            List<PlanActivity> list = null;
            while (queryResult2.hasMoreElements()) {
                Object[] obj = (Object[]) queryResult2.nextElement();
                PlanActivity activity = (PlanActivity) obj[0];
                WTUser u = (WTUser) activity.getOwnership().getOwner().getObject();
                if (acts.containsKey(u)) {
                    acts.get(u).add(activity);
                } else {
                    list = new ArrayList<>();
                    list.add(activity);
                    acts.put(u, list);
                }
            }
            if(acts.size() > 0) {
                SendEMail.emailForDelay(acts);
            }
        } catch (WTException | ParseException e) {
            e.printStackTrace();
        }
        return true;
    }
    
}
